package org.vt.eldercare.ui;

import java.awt.Frame;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JCheckBox;
import javax.swing.Box;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JOptionPane;

import java.awt.Component;
import com.jgoodies.forms.layout.FormLayout;
import com.jgoodies.forms.layout.ColumnSpec;
import com.jgoodies.forms.layout.RowSpec;
import java.awt.Dimension;
import com.jgoodies.forms.factories.FormFactory;
import javax.swing.JTextField;
import javax.swing.JSpinner;

import org.vt.eldercare.data.Node;
import org.vt.eldercare.serial.SerialWriter;
import org.vt.eldercare.serial.TwoWaySerialComm;

import javax.swing.SpinnerNumberModel;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Formatter;
import java.util.Iterator;
import java.util.List;

public class NodeConfigurationDialog extends JDialog {

	private static final String NODE_NAME_EXPORT_FLAG = "[name]";
	private static final String NODE_RATE_EXPORT_FLAG = "[rate]";
	private static final String ACCEL_EXPORT_FLAG = "[accelerometer]";
	private static final String GYRO_EXPORT_FLAG = "[gyroscope]";
	private static final String INACTIVITY_EXPORT_FLAG = "[inactivity]";
	private static final String THRESHOLD_EXPORT_FLAG = "[threshold]";
	private static final String SECONDS_EXPORT_FLAG = "[seconds]";
	private static final String ENABLE_ALL_TEXT = "Enable All Axes";
	private static final String DISABLE_ALL_TEXT = "Disable All Axes";
	private static final long serialVersionUID = 8965824665126310151L;
	private JTextField nodeNameTextField;
	private Node node;
	private TwoWaySerialComm usbComm;

	private JSpinner thresholdSpinner;
	private JSpinner waitTimeSpinner;
	private JCheckBox dynamicGyroCheckBox;
	private JCheckBox accelXCheckBox;
	private JCheckBox accelYCheckBox;
	private JCheckBox accelZCheckBox;
	private JCheckBox gyroXCheckBox;
	private JCheckBox gyroYCheckBox;
	private JCheckBox gyroZCheckBox;
	private JButton disableAccelButton;
	private JButton disableGyroButton;
	private JSpinner sampleRateSpinner;

	/**
	 * Create the dialog.
	 */
	public NodeConfigurationDialog(Frame owner, Node node) {
		super(owner);
		this.node = node;
		this.usbComm = node.getUSBComm();
		setResizable(false);
		setTitle("Edit Node Configuration");
		super.setModalityType(ModalityType.APPLICATION_MODAL);
		setBounds(100, 100, 400, 350);
		getContentPane().setLayout(
				new FormLayout(new ColumnSpec[] {
						ColumnSpec.decode("97px:grow"),
						ColumnSpec.decode("97px:grow"), }, new RowSpec[] {
						RowSpec.decode("default:grow"),
						FormFactory.RELATED_GAP_ROWSPEC,
						RowSpec.decode("88px:grow(2)"),
						FormFactory.RELATED_GAP_ROWSPEC,
						RowSpec.decode("default:grow"),
						FormFactory.RELATED_GAP_ROWSPEC,
						RowSpec.decode("default:grow"),
						FormFactory.RELATED_GAP_ROWSPEC,
						FormFactory.DEFAULT_ROWSPEC,
						FormFactory.RELATED_GAP_ROWSPEC,
						RowSpec.decode("default:grow"), }));
		{
			Box nodeNameHorizontalBox = Box.createHorizontalBox();
			getContentPane()
					.add(nodeNameHorizontalBox, "1, 1, center, default");
			{
				JLabel nodeNameLabel = new JLabel("Node Name:");
				nodeNameLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
				nodeNameHorizontalBox.add(nodeNameLabel);
			}
			{
				Component nodeNameHorizontalStrut = Box
						.createHorizontalStrut(10);
				nodeNameHorizontalBox.add(nodeNameHorizontalStrut);
			}
			{
				nodeNameTextField = new JTextField();
				nodeNameHorizontalBox.add(nodeNameTextField);
				nodeNameTextField.setColumns(10);
				nodeNameTextField.setText(this.node.getName());
			}
		}
		{
			Box sampleRateHorizontalBox = Box.createHorizontalBox();
			getContentPane().add(sampleRateHorizontalBox,
					"2, 1, center, default");
			{
				JLabel sampleRateLabel = new JLabel("Sample Rate:");
				sampleRateHorizontalBox.add(sampleRateLabel);
			}
			{
				Component sampleRateHorizontalStrut = Box
						.createHorizontalStrut(10);
				sampleRateHorizontalBox.add(sampleRateHorizontalStrut);
			}
			{
				sampleRateSpinner = new JSpinner();
				sampleRateSpinner.setModel(new SpinnerNumberModel(this.node
						.getStatus().getSamples_per_second(), 1, 30, 1));
				sampleRateSpinner.setPreferredSize(new Dimension(40, 20));
				sampleRateHorizontalBox.add(sampleRateSpinner);
			}
		}
		{
			Box accelerometerVerticalBox = Box.createVerticalBox();
			accelerometerVerticalBox.setAlignmentX(Component.CENTER_ALIGNMENT);
			getContentPane().add(accelerometerVerticalBox,
					"1, 3, center, center");
			{
				JLabel accelerometerLabel = new JLabel(
						"Enable/Disable Accelerometer:");
				accelerometerLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
				accelerometerVerticalBox.add(accelerometerLabel);
			}
			{
				accelXCheckBox = new JCheckBox("X axis");
				accelXCheckBox.addActionListener(new ActionListener() {
					public void actionPerformed(ActionEvent e) {
						if (isAccelEnabled()) {
							disableAccelButton.setText(DISABLE_ALL_TEXT);
						} else {
							disableAccelButton.setText(ENABLE_ALL_TEXT);
						}
					}
				});
				accelXCheckBox.setAlignmentX(Component.CENTER_ALIGNMENT);
				accelerometerVerticalBox.add(accelXCheckBox);
				accelXCheckBox.setSelected(this.node.getStatus()
						.isAccelXEnabled());
			}
			{
				accelYCheckBox = new JCheckBox("Y axis");
				accelYCheckBox.addActionListener(new ActionListener() {
					public void actionPerformed(ActionEvent e) {
						if (isAccelEnabled()) {
							disableAccelButton.setText(DISABLE_ALL_TEXT);
						} else {
							disableAccelButton.setText(ENABLE_ALL_TEXT);
						}
					}
				});
				accelYCheckBox.setAlignmentX(Component.CENTER_ALIGNMENT);
				accelerometerVerticalBox.add(accelYCheckBox);
				accelYCheckBox.setSelected(this.node.getStatus()
						.isAccelYEnabled());
			}
			{
				accelZCheckBox = new JCheckBox("Z axis");
				accelZCheckBox.addActionListener(new ActionListener() {
					public void actionPerformed(ActionEvent e) {
						if (isAccelEnabled()) {
							disableAccelButton.setText(DISABLE_ALL_TEXT);
						} else {
							disableAccelButton.setText(ENABLE_ALL_TEXT);
						}
					}
				});
				accelZCheckBox.setAlignmentX(Component.CENTER_ALIGNMENT);
				accelerometerVerticalBox.add(accelZCheckBox);
				accelZCheckBox.setSelected(this.node.getStatus()
						.isAccelZEnabled());
			}
			{
				String s = DISABLE_ALL_TEXT;
				if (!isAccelEnabled()) {
					s = ENABLE_ALL_TEXT;
				}
				disableAccelButton = new JButton(s);
				disableAccelButton.addActionListener(new ActionListener() {
					public void actionPerformed(ActionEvent e) {
						if (isAccelEnabled()) {
							disableAccelButton.setText(ENABLE_ALL_TEXT);
							accelXCheckBox.setSelected(false);
							accelYCheckBox.setSelected(false);
							accelZCheckBox.setSelected(false);
						} else {
							disableAccelButton.setText(DISABLE_ALL_TEXT);
							accelXCheckBox.setSelected(true);
							accelYCheckBox.setSelected(true);
							accelZCheckBox.setSelected(true);
						}
					}
				});
				disableAccelButton.setAlignmentX(Component.CENTER_ALIGNMENT);
				accelerometerVerticalBox.add(disableAccelButton);
			}
		}
		{
			Box gyroscopeVerticalBox = Box.createVerticalBox();
			gyroscopeVerticalBox.setAlignmentX(Component.CENTER_ALIGNMENT);
			getContentPane().add(gyroscopeVerticalBox, "2, 3, center, center");
			{
				JLabel gyroscopeLabel = new JLabel("Enable/Disable Gyroscope:");
				gyroscopeLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
				gyroscopeVerticalBox.add(gyroscopeLabel);
			}
			{
				gyroXCheckBox = new JCheckBox("X axis");
				gyroXCheckBox.addActionListener(new ActionListener() {
					public void actionPerformed(ActionEvent e) {
						if (isGyroEnabled()) {
							disableGyroButton.setText(DISABLE_ALL_TEXT);
						} else {
							disableGyroButton.setText(ENABLE_ALL_TEXT);
						}
					}
				});
				gyroXCheckBox.setAlignmentX(Component.CENTER_ALIGNMENT);
				gyroscopeVerticalBox.add(gyroXCheckBox);
				gyroXCheckBox.setSelected(this.node.getStatus()
						.isGyroXEnabled());
			}
			{
				gyroYCheckBox = new JCheckBox("Y axis");
				gyroYCheckBox.addActionListener(new ActionListener() {
					public void actionPerformed(ActionEvent e) {
						if (isGyroEnabled()) {
							disableGyroButton.setText(DISABLE_ALL_TEXT);
						} else {
							disableGyroButton.setText(ENABLE_ALL_TEXT);
						}
					}
				});
				gyroYCheckBox.setAlignmentX(Component.CENTER_ALIGNMENT);
				gyroscopeVerticalBox.add(gyroYCheckBox);
				gyroYCheckBox.setSelected(this.node.getStatus()
						.isGyroYEnabled());
			}
			{
				gyroZCheckBox = new JCheckBox("Z axis");
				gyroZCheckBox.addActionListener(new ActionListener() {
					public void actionPerformed(ActionEvent e) {
						if (isGyroEnabled()) {
							disableGyroButton.setText(DISABLE_ALL_TEXT);
						} else {
							disableGyroButton.setText(ENABLE_ALL_TEXT);
						}
					}
				});
				gyroZCheckBox.setAlignmentX(Component.CENTER_ALIGNMENT);
				gyroscopeVerticalBox.add(gyroZCheckBox);
				gyroZCheckBox.setSelected(this.node.getStatus()
						.isGyroZEnabled());
			}
			{
				disableGyroButton = new JButton(DISABLE_ALL_TEXT);
				disableGyroButton.addActionListener(new ActionListener() {
					public void actionPerformed(ActionEvent e) {
						if (isGyroEnabled()) {
							disableGyroButton.setText(ENABLE_ALL_TEXT);
							gyroXCheckBox.setSelected(false);
							gyroYCheckBox.setSelected(false);
							gyroZCheckBox.setSelected(false);
						} else {
							disableGyroButton.setText(DISABLE_ALL_TEXT);
							gyroXCheckBox.setSelected(true);
							gyroYCheckBox.setSelected(true);
							gyroZCheckBox.setSelected(true);
						}
					}
				});
				disableGyroButton.setAlignmentX(Component.CENTER_ALIGNMENT);
				gyroscopeVerticalBox.add(disableGyroButton);
			}
		}
		{
			dynamicGyroCheckBox = new JCheckBox(
					"Disable gyroscope during periods of inactivity?");
			dynamicGyroCheckBox.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent arg0) {
					thresholdSpinner.setEnabled(dynamicGyroCheckBox
							.isSelected());
					waitTimeSpinner.setEnabled(dynamicGyroCheckBox.isSelected());
				}
			});
			getContentPane().add(dynamicGyroCheckBox,
					"1, 5, 2, 1, center, default");
			dynamicGyroCheckBox.setSelected(this.node.getStatus()
					.isInactivityDetectEnabled());
		}
		{
			Box thresholdHorizontalBox = Box.createHorizontalBox();
			getContentPane().add(thresholdHorizontalBox,
					"1, 7, center, default");
			{
				JLabel thresholdLabel = new JLabel("Inactivity Threshold:");
				thresholdHorizontalBox.add(thresholdLabel);
			}
			{
				Component thresholdHorizontalStrut = Box
						.createHorizontalStrut(10);
				thresholdHorizontalBox.add(thresholdHorizontalStrut);
			}
			{
				thresholdSpinner = new JSpinner();
				thresholdSpinner.setModel(new SpinnerNumberModel(this.node
						.getStatus().getInactivityThreshold(),
						SerialWriter.MIN_THRESHOLD_VALUE,
						SerialWriter.MAX_THRESHOLD_VALUE,
						SerialWriter.THRESHOLD_INCREMENT));
				thresholdSpinner.setPreferredSize(new Dimension(40, 20));
				thresholdHorizontalBox.add(thresholdSpinner);
			}
		}
		{
			Box waitTimeHorizontalBox = Box.createHorizontalBox();
			getContentPane()
					.add(waitTimeHorizontalBox, "2, 7, center, default");
			{
				JLabel waitTimeLabel = new JLabel("Seconds to Wait:");
				waitTimeHorizontalBox.add(waitTimeLabel);
			}
			{
				Component waitTimeHorizontalStrut = Box
						.createHorizontalStrut(10);
				waitTimeHorizontalBox.add(waitTimeHorizontalStrut);
			}
			{
				waitTimeSpinner = new JSpinner();
				waitTimeSpinner.setModel(new SpinnerNumberModel(this.node
						.getStatus().getInactivityWaittime(), 1, 30, 1));
				waitTimeSpinner.setPreferredSize(new Dimension(40, 20));
				waitTimeHorizontalBox.add(waitTimeSpinner);
			}
		}
		{
			JButton importButton = new JButton("Import Node Configuration...");
			importButton.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent arg0) {
					JFileChooser fc = new JFileChooser((File) null);
					fc.setFileFilter(new NodeConfigFilter());
					fc.setMultiSelectionEnabled(false);
					if (fc.showOpenDialog(NodeConfigurationDialog.this) == JFileChooser.APPROVE_OPTION) {
						File selectedFile = fc.getSelectedFile();
						if (Utils.getExtension(selectedFile).equals(
								Utils.nodeconfig)) {
							try {
								importNodeConfig(selectedFile);
							} catch (FileNotFoundException e) {
								e.printStackTrace();
							} catch (IOException e) {
								e.printStackTrace();
							}
						} else {
							JOptionPane.showMessageDialog(
									NodeConfigurationDialog.this,
									"File must be a Node Configuration File (."
											+ Utils.nodeconfig + ").", "Error",
									JOptionPane.ERROR_MESSAGE);
						}
					}
				}
			});
			getContentPane().add(importButton, "1, 9, center, default");
		}
		{
			JButton exportButton = new JButton("Export Node Configuration...");
			exportButton.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent arg0) {
					JFileChooser fc = new JFileChooser((File) null);
					fc.setFileFilter(new NodeConfigFilter());
					if (fc.showSaveDialog(NodeConfigurationDialog.this) == JFileChooser.APPROVE_OPTION) {
						File selectedFile = fc.getSelectedFile();
						try {
							if (Utils.getExtension(selectedFile).equals(
									Utils.nodeconfig)) {
								exportNodeConfig(selectedFile);
							} else {
								exportNodeConfig(new File(selectedFile
										.getAbsolutePath()
										+ "."
										+ Utils.nodeconfig));
							}
						} catch (FileNotFoundException e1) {
							e1.printStackTrace();
						}
					}
				}
			});
			getContentPane().add(exportButton, "2, 9, center, default");
		}
		{
			Box buttonHorizontalBox = Box.createHorizontalBox();
			getContentPane().add(buttonHorizontalBox,
					"1, 11, 2, 1, right, default");
			{
				JButton okButton = new JButton("OK");
				okButton.addActionListener(new ActionListener() {
					public void actionPerformed(ActionEvent e) {
						NodeConfigurationDialog.this.usbComm.serialWrite(
								NodeConfigurationDialog.this.node.getNodeID(),
								getCommands());
						NodeConfigurationDialog.this.node
								.setName(nodeNameTextField.getText());
						NodeConfigurationDialog.this.dispose();
					}
				});
				buttonHorizontalBox.add(okButton);
			}
			{
				Component buttonHorizontalStrut4 = Box
						.createHorizontalStrut(10);
				buttonHorizontalBox.add(buttonHorizontalStrut4);
			}
			{
				JButton resetButton = new JButton("Reset");
				resetButton.addActionListener(new ActionListener() {
					public void actionPerformed(ActionEvent e) {
						nodeNameTextField
								.setText(NodeConfigurationDialog.this.node
										.getName());
						Node.Status status = NodeConfigurationDialog.this.node
								.getStatus();
						sampleRateSpinner.setValue(status
								.getSamples_per_second());
						thresholdSpinner.setValue(status
								.getInactivityThreshold());
						waitTimeSpinner.setValue(status.getInactivityWaittime());
						dynamicGyroCheckBox.setSelected(status
								.isInactivityDetectEnabled());
						accelXCheckBox.setSelected(status.isAccelXEnabled());
						accelYCheckBox.setSelected(status.isAccelYEnabled());
						accelZCheckBox.setSelected(status.isAccelZEnabled());
						gyroXCheckBox.setSelected(status.isGyroXEnabled());
						gyroYCheckBox.setSelected(status.isGyroYEnabled());
						gyroZCheckBox.setSelected(status.isGyroZEnabled());
						if (isGyroEnabled()) {
							disableAccelButton.setText(DISABLE_ALL_TEXT);
						} else {
							disableAccelButton.setText(ENABLE_ALL_TEXT);
						}
						if (isGyroEnabled()) {
							disableGyroButton.setText(DISABLE_ALL_TEXT);
						} else {
							disableGyroButton.setText(ENABLE_ALL_TEXT);
						}
					}
				});
				buttonHorizontalBox.add(resetButton);
			}
			{
				Component buttonHorizontalStrut1 = Box
						.createHorizontalStrut(10);
				buttonHorizontalBox.add(buttonHorizontalStrut1);
			}
			{
				JButton defaultsButton = new JButton("Defaults");
				defaultsButton.addActionListener(new ActionListener() {
					public void actionPerformed(ActionEvent e) {
						nodeNameTextField
								.setText(NodeConfigurationDialog.this.node
										.getNodeID() + "");
						sampleRateSpinner
								.setValue(Node.Status.DEFAULT_SAMPLES_PER_SECOND);
						thresholdSpinner
								.setValue(Node.Status.DEFAULT_INACTIVITY_DETECT_THRESHOLD);
						waitTimeSpinner
								.setValue(Node.Status.DEFAULT_INACTIVITY_WAIT_TIME);
						dynamicGyroCheckBox
								.setSelected(Node.Status.DEFAULT_INACTIVITY_DETECT_ENABLED);
						accelXCheckBox
								.setSelected(Node.Status.DEFAULT_ACCEL_X_ENABLED);
						accelYCheckBox
								.setSelected(Node.Status.DEFAULT_ACCEL_Y_ENABLED);
						accelZCheckBox
								.setSelected(Node.Status.DEFAULT_ACCEL_Z_ENABLED);
						gyroXCheckBox
								.setSelected(Node.Status.DEFAULT_GYRO_X_ENABLED);
						gyroYCheckBox
								.setSelected(Node.Status.DEFAULT_GYRO_Y_ENABLED);
						gyroZCheckBox
								.setSelected(Node.Status.DEFAULT_GYRO_Z_ENABLED);
						if (isAccelEnabled()) {
							disableAccelButton.setText(DISABLE_ALL_TEXT);
						} else {
							disableAccelButton.setText(ENABLE_ALL_TEXT);
						}
						if (isGyroEnabled()) {
							disableGyroButton.setText(DISABLE_ALL_TEXT);
						} else {
							disableGyroButton.setText(ENABLE_ALL_TEXT);
						}
					}
				});
				buttonHorizontalBox.add(defaultsButton);
			}
			{
				Component buttonHorizontalStrut2 = Box
						.createHorizontalStrut(10);
				buttonHorizontalBox.add(buttonHorizontalStrut2);
			}
			{
				JButton cancelButton = new JButton("Cancel");
				cancelButton.addActionListener(new ActionListener() {
					public void actionPerformed(ActionEvent e) {
						NodeConfigurationDialog.this.dispose();
					}
				});
				buttonHorizontalBox.add(cancelButton);
			}
			{
				Component buttonHorizontalStrut3 = Box
						.createHorizontalStrut(10);
				buttonHorizontalBox.add(buttonHorizontalStrut3);
			}
		}
	}

	protected void exportNodeConfig(File selectedFile)
			throws FileNotFoundException {
		Formatter fmt = new Formatter(selectedFile);
		fmt.format("%-20s%s\r\n", NODE_NAME_EXPORT_FLAG,
				nodeNameTextField.getText());
		fmt.format("%-20s%d\r\n", NODE_RATE_EXPORT_FLAG,
				sampleRateSpinner.getValue());
		String temp = "";
		if (accelXCheckBox.isSelected()) {
			temp += "X ";
		}
		if (accelYCheckBox.isSelected()) {
			temp += "Y ";
		}
		if (accelZCheckBox.isSelected()) {
			temp += "Z";
		}
		fmt.format("%-20s%s\r\n", ACCEL_EXPORT_FLAG, temp);
		temp = "";
		if (gyroXCheckBox.isSelected()) {
			temp += "X ";
		}
		if (gyroYCheckBox.isSelected()) {
			temp += "Y ";
		}
		if (gyroZCheckBox.isSelected()) {
			temp += "Z";
		}
		fmt.format("%-20s%s\r\n", GYRO_EXPORT_FLAG, temp);
		temp = "";
		if (dynamicGyroCheckBox.isSelected()) {
			temp = "Yes";
		} else {
			temp = "No";
		}
		fmt.format("%-20s%s\r\n", INACTIVITY_EXPORT_FLAG, temp);
		if (dynamicGyroCheckBox.isSelected()) {
			fmt.format("%-20s%d\r\n", THRESHOLD_EXPORT_FLAG,
					thresholdSpinner.getValue());
			fmt.format("%-20s%d\r\n", SECONDS_EXPORT_FLAG,
					waitTimeSpinner.getValue());
		}
		fmt.flush();
		fmt.close();
	}

	protected void importNodeConfig(File selectedFile) throws IOException {
		BufferedReader br = new BufferedReader(new FileReader(selectedFile));
		String line = null;
		do {
			line = br.readLine();
			if (line != null)
				parseInput(line);
		} while (line != null);
		br.close();
	}

	private void parseInput(String line) {
		if (line.contains(NODE_NAME_EXPORT_FLAG)) {
			String s = line.replace(NODE_NAME_EXPORT_FLAG, "");
			nodeNameTextField.setText(s.trim());
		} else if (line.contains(NODE_RATE_EXPORT_FLAG)) {
			String s = line.replace(NODE_RATE_EXPORT_FLAG, "");
			int value = Integer.parseInt(s.trim());
			if (value > 30) {
				value = 30;
			}
			if (value < 1) {
				value = 1;
			}
			sampleRateSpinner.setValue(value);
		} else if (line.contains(ACCEL_EXPORT_FLAG)) {
			String s = line.replace(ACCEL_EXPORT_FLAG, "");
			accelXCheckBox.setSelected(s.contains("X"));
			accelYCheckBox.setSelected(s.contains("Y"));
			accelZCheckBox.setSelected(s.contains("Z"));
		} else if (line.contains(GYRO_EXPORT_FLAG)) {
			String s = line.replace(GYRO_EXPORT_FLAG, "");
			gyroXCheckBox.setSelected(s.contains("X"));
			gyroYCheckBox.setSelected(s.contains("Y"));
			gyroZCheckBox.setSelected(s.contains("Z"));
		} else if (line.contains(INACTIVITY_EXPORT_FLAG)) {
			String s = line.replace(INACTIVITY_EXPORT_FLAG, "");
			if (s.trim().contains("Y")) {
				dynamicGyroCheckBox.setSelected(true);
			} else if (s.trim().contains("N")) {
				dynamicGyroCheckBox.setSelected(false);
			}
		} else if (line.contains(THRESHOLD_EXPORT_FLAG)) {
			String s = line.replace(THRESHOLD_EXPORT_FLAG, "");
			int value = Integer.parseInt(s.trim());
			if (value > 30) {
				value = 30;
			}
			if (value < 5) {
				value = 5;
			}
			value = 5 * (value / 5);
			thresholdSpinner.setValue(value);
		} else if (line.contains(SECONDS_EXPORT_FLAG)) {
			String s = line.replace(SECONDS_EXPORT_FLAG, "");
			int value = Integer.parseInt(s.trim());
			if (value > 30) {
				value = 30;
			}
			if (value < 1) {
				value = 1;
			}
			waitTimeSpinner.setValue(value);
		}
		thresholdSpinner.setEnabled(dynamicGyroCheckBox.isSelected());
		waitTimeSpinner.setEnabled(dynamicGyroCheckBox.isSelected());
	}

	private boolean isAccelEnabled() {
		return accelXCheckBox.isSelected() | accelYCheckBox.isSelected()
				| accelZCheckBox.isSelected();
	}

	private boolean isGyroEnabled() {
		return gyroXCheckBox.isSelected() | gyroYCheckBox.isSelected()
				| gyroZCheckBox.isSelected();
	}

	private byte[] getCommands() {
		Node.Status status = NodeConfigurationDialog.this.node.getStatus();
		NodeStatusDisplay display = NodeConfigurationDialog.this.node
				.getStatusDisplay();
		List<Byte> commands = new ArrayList<Byte>();
		if ((Integer) sampleRateSpinner.getValue() != status
				.getSamples_per_second()) {
			commands.add(SerialWriter.SAMPLE_RATE((Integer) sampleRateSpinner
					.getValue()));
			status.setSamples_per_second((Integer) sampleRateSpinner.getValue());
		}
		if (accelXCheckBox.isSelected() != status.isAccelXEnabled()) {
			display.pendingAccelX();
			if (accelXCheckBox.isSelected()) {
				commands.add(SerialWriter.ENABLE_ACCELEROMETER_X);
			} else {
				commands.add(SerialWriter.DISABLE_ACCELEROMETER_X);
			}
		}
		if (accelYCheckBox.isSelected() != status.isAccelYEnabled()) {
			display.pendingAccelY();
			if (accelYCheckBox.isSelected()) {
				commands.add(SerialWriter.ENABLE_ACCELEROMETER_Y);
			} else {
				commands.add(SerialWriter.DISABLE_ACCELEROMETER_Y);
			}
		}
		if (accelZCheckBox.isSelected() != status.isAccelZEnabled()) {
			display.pendingAccelZ();
			if (accelZCheckBox.isSelected()) {
				commands.add(SerialWriter.ENABLE_ACCELEROMETER_Z);
			} else {
				commands.add(SerialWriter.DISABLE_ACCELEROMETER_Z);
			}
		}
		if (gyroXCheckBox.isSelected() != status.isGyroXEnabled()) {
			display.pendingGyroX();
			if (gyroXCheckBox.isSelected()) {
				commands.add(SerialWriter.ENABLE_GYRO_X);
			} else {
				commands.add(SerialWriter.DISABLE_GYRO_X);
			}
		}
		if (gyroYCheckBox.isSelected() != status.isGyroYEnabled()) {
			display.pendingGyroY();
			if (gyroYCheckBox.isSelected()) {
				commands.add(SerialWriter.ENABLE_GYRO_Y);
			} else {
				commands.add(SerialWriter.DISABLE_GYRO_Y);
			}
		}
		if (gyroZCheckBox.isSelected() != status.isGyroZEnabled()) {
			display.pendingGyroZ();
			if (gyroZCheckBox.isSelected()) {
				commands.add(SerialWriter.ENABLE_GYRO_Z);
			} else {
				commands.add(SerialWriter.DISABLE_GYRO_Z);
			}
		}
		if (dynamicGyroCheckBox.isSelected() != status
				.isInactivityDetectEnabled()) {
			if (dynamicGyroCheckBox.isSelected()) {
				commands.add(SerialWriter.ENABLE_INACTIVITY_DETECT);
			} else {
				commands.add(SerialWriter.DISABLE_INACTIVITY_DETECT);
			}
			status.setInactivityDetectEnabled(dynamicGyroCheckBox.isSelected());
		}
		if (dynamicGyroCheckBox.isSelected()) {
			if ((Integer) thresholdSpinner.getValue() != status
					.getInactivityThreshold()) {
				commands.add(SerialWriter
						.INACTIVITY_DETECT_THRESHOLD((Integer) thresholdSpinner
								.getValue()));
				status.setInactivityThreshold((Integer) thresholdSpinner
						.getValue());
			}
			if ((Integer) waitTimeSpinner.getValue() != status
					.getInactivityWaittime()) {
				commands.add(SerialWriter
						.INACTIVITY_DETECT_WAITTIME((Integer) waitTimeSpinner
								.getValue()));
				status.setInactivityWaittime((Integer) waitTimeSpinner
						.getValue());
			}
		}
		return toPrimitive(commands);
	}

	private byte[] toPrimitive(List<Byte> list) {
		byte[] returnVal = new byte[list.size()];
		Iterator<Byte> iterator = list.iterator();
		for (int i = 0; i < returnVal.length; i++) {
			returnVal[i] = iterator.next().byteValue();
		}
		return returnVal;
	}
}
